package com.lefevre.cms.service.help.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lefevre.cms.bean.help.Help;
import com.lefevre.cms.bean.help.HelpType;
import com.lefevre.cms.mapper.HelpMapper;
import com.lefevre.cms.mapper.HelpTypeMapper;
import com.lefevre.cms.service.help.HelpService;
import com.lefevre.cms.service.help.HelpTypeService;
import com.lefevre.cms.web.action.SystemException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * 帮助管理
 *
 * @author Lefevre
 */
@Service
@Transactional
public class HelpTypeServiceImpl extends ServiceImpl<HelpTypeMapper, HelpType> implements HelpTypeService {

    @Resource
    HelpService helpService;
    @Resource
    private HelpMapper helpMapper;

    /**
     * 根据Id查询帮助分类
     *
     * @param helpTypeId 帮助分类Id
     * @return
     */
    @Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED)
    public HelpType findById(Long helpTypeId) {
        return baseMapper.selectById(helpTypeId);
    }

    /**
     * 根据Id查询帮助分类
     *
     * @param helpTypeIdList 帮助分类Id集合
     * @return
     */
    @Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED)
    public List<HelpType> findByIdList(List<Long> helpTypeIdList) {
        return baseMapper.selectBatchIds(helpTypeIdList);
    }

    /**
     * 查询所有帮助分类
     *
     * @return
     */
    @Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED)
    public List<HelpType> findAllHelpType() {
        return baseMapper.selectList(null);
    }

    /**
     * 根据Id组查询子分类
     *
     * @param idGroup 帮助分类Id组
     * @return
     */
    @Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED)
    public List<HelpType> findChildHelpTypeByIdGroup(String idGroup) {
        return baseMapper.selectList(new LambdaQueryWrapper<HelpType>()
                .like(HelpType::getParentIdGroup, idGroup));
    }

    /**
     * 增加帮助数量
     *
     * @param helpTypeId 帮助分类Id
     */
    public Integer addHelpQuantity(Long helpTypeId) {
        HelpType helpType = baseMapper.selectOne(new LambdaQueryWrapper<HelpType>()
                .eq(HelpType::getId, helpTypeId)
                .eq(HelpType::getChildNodeNumber, 0));
        helpType.setTotalHelp(helpType.getTotalHelp() + 1);
        helpType.setHelpQuantity(helpType.getHelpQuantity() + 1);

        return baseMapper.updateById(helpType);
    }

    /**
     * 减少帮助数量
     *
     * @param helpTypeId   帮助分类Id
     * @param helpQuantity 帮助数量(显示)
     */
    public Integer minusHelpQuantity(Long helpTypeId, Long helpQuantity) {
        HelpType helpType = baseMapper.selectOne(new LambdaQueryWrapper<HelpType>()
                .eq(HelpType::getId, helpTypeId)
                .gt(HelpType::getHelpQuantity, helpQuantity));
        helpType.setTotalHelp(helpType.getTotalHelp() - 1);
        helpType.setHelpQuantity(helpType.getHelpQuantity() - 1);

        return baseMapper.updateById(helpType);
    }

    /**
     * 标记删除增加帮助数量
     *
     * @param helpTypeId 帮助分类Id
     */
    public Integer mark_addHelpQuantity(Long helpTypeId) {
        HelpType helpType = baseMapper.selectOne(new LambdaQueryWrapper<HelpType>()
                .eq(HelpType::getId, helpTypeId)
                .eq(HelpType::getChildNodeNumber, 0));
        helpType.setHelpQuantity(helpType.getHelpQuantity() + 1);

        return baseMapper.updateById(helpType);
    }

    /**
     * 标记删除减少帮助数量
     *
     * @param helpTypeId 帮助分类Id
     */
    public Integer mark_minusHelpQuantity(Long helpTypeId) {
        HelpType helpType = baseMapper.selectOne(new LambdaQueryWrapper<HelpType>()
                .eq(HelpType::getId, helpTypeId)
                .gt(HelpType::getHelpQuantity, 0));
        helpType.setHelpQuantity(helpType.getHelpQuantity() - 1);

        return baseMapper.updateById(helpType);
    }


    /**
     * 保存帮助分类
     */
    public void saveType(HelpType helpType) {

        int insert = baseMapper.insert(helpType);

        //如果不是根节点
        if (!helpType.getParentId().equals(0L)) {
            //修改父节点叶子节点状态
            HelpType type = baseMapper.selectById(helpType.getParentId());
            type.setChildNodeNumber(type.getChildNodeNumber() + 1);
            int i = baseMapper.updateById(type);
            if (i == 0) {
                throw new SystemException("父节点不存在");
            }
            HelpType parentHelpType = this.findById(helpType.getParentId());
            //帮助总数量(显示+回收站)
            Long totalHelp = 0L;
            //帮助数量(显示)
            Long helpQuantity = 0L;
            //已合并分类Id
            String mergerTypeId = ",";
            if (parentHelpType != null) {
                totalHelp = parentHelpType.getTotalHelp();
                helpQuantity = parentHelpType.getHelpQuantity();
                mergerTypeId = parentHelpType.getMergerTypeId();
            }
            //验证上级节点原来是根节点才执行
            HelpType one = baseMapper.selectOne(new LambdaQueryWrapper<HelpType>()
                    .eq(HelpType::getId, helpType.getParentId())
                    .eq(HelpType::getChildNodeNumber, 1));

            if (one != null) {
                one.setChildNodeNumber(1);
                one.setTotalHelp(0L);
                one.setHelpQuantity(0L);
                one.setMergerTypeId(",");
                int j = baseMapper.updateById(one);

                if (j > 0) {
                    //将父节点帮助数量转到本节点
                    HelpType dbType = baseMapper.selectById(helpType.getId());
                    dbType.setTotalHelp(totalHelp);
                    dbType.setHelpQuantity(helpQuantity);
                    dbType.setMergerTypeId(mergerTypeId);
                    baseMapper.updateById(dbType);
                    //将父节点下的分类帮助转到本节点
                    helpService.updateHelpTypeId(helpType.getParentId(), helpType.getId());
                }
            }
        }
    }

    /**
     * 修改帮助分类
     *
     * @param helpType 帮助分类
     */
    public Integer updateHelpType(HelpType helpType) {
        return baseMapper.updateById(helpType);
    }


    /**
     * 删除帮助分类
     *
     * @param helpType 帮助分类
     */
    public Integer deleteHelpType(HelpType helpType) {
        int i = baseMapper.deleteById(helpType.getId());
        if (i > 0) {
            if (helpType.getParentId() > 0L) {
                //将父类计数减一
                HelpType type = baseMapper.selectById(helpType.getParentId());
                type.setChildNodeNumber(type.getChildNodeNumber() - 1);
                baseMapper.updateById(type);
            }
            //删除分类下帮助
            i = helpMapper.deleteById(helpType.getId());
            this.deleteChildNode(Collections.singletonList(helpType.getId()));
        }
        return i;
    }

    /**
     * 递归删除子节点下帮助
     */
    private void deleteChildNode(List<Long> typeIdList) {
        List<Long> idList = new ArrayList<>();
        for (Long typeId : typeIdList) {
            List<HelpType> helpTypeList = baseMapper.selectList(new LambdaQueryWrapper<HelpType>().eq(HelpType::getParentId, typeId));
            if (helpTypeList != null && helpTypeList.size() > 0) {
                for (HelpType p : helpTypeList) {
                    //删除当前节点
                    baseMapper.deleteById(p.getId());
                    if (p.getChildNodeNumber() > 0) {
                        idList.add(p.getId());
                    } else {//如果是最后一个节点
                        //删除分类下帮助
                        helpMapper.delete(new LambdaUpdateWrapper<Help>().eq(Help::getHelpTypeId, p.getId()));
                    }
                }
            }
        }
        if (idList.size() > 0) {
            deleteChildNode(idList);
        }
    }


    /**
     * 根据分类查询所有父类帮助分类
     *
     * @param helpType 分类
     * @return
     */
    @Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED)
    public List<HelpType> findAllParentById(HelpType helpType) {
        List<HelpType> helpTypeList = new ArrayList<>();
        //查询所有父类
        if (helpType.getParentId() > 0) {
            List<HelpType> list = this.findParentById(helpType.getParentId(), new ArrayList<HelpType>());
            helpTypeList.addAll(list);
        }
        //倒转顺序
        Collections.reverse(helpTypeList);
        return helpTypeList;
    }

    /**
     * 根据ID查询帮助父类 (递归)
     *
     * @param parentId     父分类ID
     * @param helpTypeList 父分类集合
     * @return
     */
    @Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED)
    public List<HelpType> findParentById(Long parentId, List<HelpType> helpTypeList) {
        HelpType parentHelpType = this.findById(parentId);
        if (parentHelpType != null) {
            helpTypeList.add(parentHelpType);
            if (parentHelpType.getParentId() > 0L) {
                this.findParentById(parentHelpType.getParentId(), helpTypeList);
            }
        }
        return helpTypeList;
    }

    /**
     * 合并商品分类
     *
     * @param helpTypeId     原商品分类
     * @param mergerHelpType 待合并商品分类
     * @return
     */
    public Integer mergerHelpType(Long helpTypeId, HelpType mergerHelpType) {
        HelpType helpType = baseMapper.selectById(helpTypeId);
        helpType.setTotalHelp(helpType.getTotalHelp() + mergerHelpType.getTotalHelp());
        helpType.setHelpQuantity(helpType.getHelpQuantity() + mergerHelpType.getHelpQuantity());
        helpType.setMergerTypeId(mergerHelpType.getId() + mergerHelpType.getMergerTypeId());

        int i = baseMapper.updateById(helpType);
        int i_delete = baseMapper.deleteById(mergerHelpType.getId());
        i += i_delete;
        if (i_delete > 0) {
            if (mergerHelpType.getParentId() > 0L) {
                //将父类计数减一
                // Query query_ = em.createQuery("update HelpType o set o.childNodeNumber=childNodeNumber-1 where o.id=?1")
                //         .setParameter(1, mergerHelpType.getParentId());
                // query_.executeUpdate();
                HelpType type = baseMapper.selectById(mergerHelpType.getParentId());
                type.setChildNodeNumber(type.getChildNodeNumber() - 1);
                baseMapper.updateById(type);
            }
        }
        //修改帮助分类参数
        helpMapper.update(null, new LambdaUpdateWrapper<Help>()
                .set(Help::getHelpTypeId, helpTypeId)
                .eq(Help::getHelpTypeId, mergerHelpType.getId()));
        return i;
    }

}
